<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta
            http-equiv="Content-Type"
            content="text/html; charset=utf-8"
        />
        <meta name="viewport" content="width=device-width, initial-scale=1" />

        <title>Webhook Client &mdash; Python Slack SDK</title>

        <!-- Google Tag Manager -->
        <script>
            (function(w, d, s, l, i) {
                w[l] = w[l] || [];
                w[l].push({
                    'gtm.start': new Date().getTime(),
                    event: 'gtm.js'
                });
                var f = d.getElementsByTagName(s)[0],
                    j = d.createElement(s),
                    dl = l != 'dataLayer' ? '&l=' + l : '';
                j.async = true;
                j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
                f.parentNode.insertBefore(j, f);
            })(window, document, 'script', 'dataLayer', 'GTM-KFZ5MK7');
        </script>
        <!-- End Google Tag Manager -->
        
        <link
            href="https://a.slack-edge.com/4f227/style/rollup-slack_kit_legacy_adapters.css"
            rel="stylesheet"
            type="text/css"
        />
        <link
            href="https://a.slack-edge.com/3e02c0/style/rollup-api_site.css"
            rel="stylesheet"
            type="text/css"
        />
        <link
            rel="stylesheet"
            href=".././assets/default.css"
            type="text/css"
        />
        <link
            rel="stylesheet"
            href=".././assets/pygments.css"
            type="text/css"
        />
        <link
            rel="stylesheet"
            href=".././assets/docs.css"
            type="text/css"
        />
        <link
            id="favicon"
            rel="shortcut icon"
            href="https://a.slack-edge.com/4f28/img/icons/favicon-32.png"
            type="image/png"
        />
        <link
            rel="top"
            title="Python Slack SDK 1.0.1 documentation"
            href="../index.html"
        />
    </head>

    <body class="api light_theme">
        <!-- Google Tag Manager (noscript) -->
        <noscript
            ><iframe
                src="https://www.googletagmanager.com/ns.html?id=GTM-KFZ5MK7"
                height="0"
                width="0"
                style="display:none;visibility:hidden"
            ></iframe
        ></noscript>
        <!-- End Google Tag Manager (noscript) -->
        <header>
            <a id="menu_toggle" class="no_transition show_on_mobile">
                <span class="menu_icon"></span>
                <span class="vert_divider"></span>
            </a>
            <a
                href="https://api.slack.com/"
                id="header_logo"
                class="api hide_on_mobile"
                style="float:left; display: inline-block;"
            >
                <img
                    alt="Slack API"
                    src="https://a.slack-edge.com/3026cb/img/slack_api_logo_vogue.png"
                    style="width: 225px; padding-right: 25px; border-right: 1px solid #DDD;"
                />
            </a>
            <span
                style="display: inline-block; padding-left: 20px; margin-top: 25px; font-weight: bold;"
            >
                <a style="color: #555459;" href="./index.html">Python Slack SDK</a>
            </span>
            <div class="header_nav">
                <a
                    href="https://github.com/SlackAPI/python-slack-sdk"
                    class="btn header_btn float_right"
                    data-qa="go_to_slack"
                    >Go to GitHub</a
                >
            </div>
        </header>
        

        <div id="page">
            <div id="page_contents" class="clearfix">
                <!-- Sidebar Content -->
                <nav id="api_nav" class="col span_1_of_4">
                    <div id="api_sections">
                         <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../index.html">Python Slack SDK</a></li>
<li class="toctree-l1"><a class="reference internal" href="../v3-migration/index.html">Migration Guide</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../v3-migration/index.html#from-slackclient-2-x">From slackclient 2.x</a></li>
<li class="toctree-l2"><a class="reference internal" href="../v3-migration/index.html#from-slackclient-1-x">From slackclient 1.x</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../installation/index.html">Installation</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../installation/index.html#access-tokens">Access Tokens</a></li>
<li class="toctree-l2"><a class="reference internal" href="../installation/index.html#workspace-installations">Workspace Installations</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../web/index.html">Web Client</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../web/index.html#messaging">Messaging</a></li>
<li class="toctree-l2"><a class="reference internal" href="../web/index.html#files">Files</a></li>
<li class="toctree-l2"><a class="reference internal" href="../web/index.html#conversations">Conversations</a></li>
<li class="toctree-l2"><a class="reference internal" href="../web/index.html#modals">Modals</a></li>
<li class="toctree-l2"><a class="reference internal" href="../web/index.html#rate-limits">Rate Limits</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../web/index.html#calling-any-api-methods">Calling any API methods</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../web/index.html#asyncwebclient">AsyncWebClient</a></li>
<li class="toctree-l2"><a class="reference internal" href="../web/index.html#retryhandler">RetryHandler</a></li>
</ul>
</li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">Webhook Client</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#id1">Incoming Webhooks</a></li>
<li class="toctree-l2"><a class="reference internal" href="#response-url">response_url</a></li>
<li class="toctree-l2"><a class="reference internal" href="#asyncwebhookclient">AsyncWebhookClient</a></li>
<li class="toctree-l2"><a class="reference internal" href="#retryhandler">RetryHandler</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../socket-mode/index.html">Socket Mode Client</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../socket-mode/index.html#socketmodeclient">SocketModeClient</a></li>
<li class="toctree-l2"><a class="reference internal" href="../socket-mode/index.html#supported-libraries">Supported Libraries</a></li>
<li class="toctree-l2"><a class="reference internal" href="../socket-mode/index.html#asyncio-based-libraries">Asyncio Based Libraries</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../oauth/index.html">OAuth Modules</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../oauth/index.html#app-installation-flow">App Installation Flow</a></li>
<li class="toctree-l2"><a class="reference internal" href="../oauth/index.html#token-lookup">Token Lookup</a></li>
<li class="toctree-l2"><a class="reference internal" href="../oauth/index.html#sign-in-with-slack">Sign in with Slack</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../audit-logs/index.html">Audit Logs API Client</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../audit-logs/index.html#auditlogsclient">AuditLogsClient</a></li>
<li class="toctree-l2"><a class="reference internal" href="../audit-logs/index.html#asyncauditlogsclient">AsyncAuditLogsClient</a></li>
<li class="toctree-l2"><a class="reference internal" href="../audit-logs/index.html#retryhandler">RetryHandler</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../scim/index.html">SCIM API Client</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../scim/index.html#scimclient">SCIMClient</a></li>
<li class="toctree-l2"><a class="reference internal" href="../scim/index.html#asyncscimclient">AsyncSCIMClient</a></li>
<li class="toctree-l2"><a class="reference internal" href="../scim/index.html#retryhandler">RetryHandler</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../real_time_messaging.html">RTM Client</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../real_time_messaging.html#real-time-messaging-rtm">Real Time Messaging (RTM)</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../faq.html">FAQ</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../faq.html#python-documents">Python Documents</a></li>
<li class="toctree-l2"><a class="reference internal" href="../faq.html#installation-issues">Installation Issues</a></li>
<li class="toctree-l2"><a class="reference internal" href="../faq.html#bug-report">Bug Report</a></li>
<li class="toctree-l2"><a class="reference internal" href="../faq.html#feature-requests">Feature Requests</a></li>
<li class="toctree-l2"><a class="reference internal" href="../faq.html#contributions">Contributions</a></li>
<li class="toctree-l2"><a class="reference internal" href="../faq.html#documentation">Documentation</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../about.html">About</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../about.html#product-name">Python Slack SDK</a></li>
</ul>
</li>
</ul>


<div id="footer">

        <ul id="footer_nav">
                <li><a href="https://github.com/SlackAPI/python-slack-sdk/blob/main/LICENSE">License</a></li>
                <li><a href="https://slackhq.github.io/code-of-conduct">Code of Conduct</a></li>
                <li><a href="https://github.com/slackapi/python-slack-sdk/blob/main/.github/contributing.md">Contributing</a></li>
                <li><a href="https://docs.google.com/a/slack-corp.com/forms/d/e/1FAIpQLSfzjVoCM7ohBnjWf7eDYQxzti1EPpinsIJQA5RAUBwJKRUQHg/viewform">Contributor License Agreement</a></li>
        </ul>

        <p id="footer_signature">Made with <i class="ts_icon ts_icon_heart"></i> by Slack<br/>and our Lovely
                Community
        </p>
</div> 
                    </div>
                </nav>
                <!-- /Sidebar Content -->

                <!-- Body Content -->
                <div class="col span_3_of_4">
                    <!-- <div class="section-title">Webhook Client</div> -->
                    <div class="card">
  <section id="webhook-client">
<h1>Webhook Client<a class="headerlink" href="#webhook-client" title="Link to this heading">¶</a></h1>
<p>You can use <code class="docutils literal notranslate"><span class="pre">slack_sdk.webhook.WebhookClient</span></code> for <a class="reference external" href="https://api.slack.com/messaging/webhooks">Incoming Webhooks</a> and message responses using <a class="reference external" href="https://api.slack.com/interactivity/handling#message_responses">response_url in payloads</a>.</p>
<p>The Python document for this module is available at <a class="reference external" href="https://slack.dev/python-slack-sdk/api-docs/slack_sdk/">https://slack.dev/python-slack-sdk/api-docs/slack_sdk/</a></p>
<section id="id1">
<h2>Incoming Webhooks<a class="headerlink" href="#id1" title="Link to this heading">¶</a></h2>
<p>To use <a class="reference external" href="https://api.slack.com/messaging/webhooks">Incoming Webhooks</a>, just calling <code class="docutils literal notranslate"><span class="pre">WebhookClient(url)#send(payload)</span></code> method works for you. The call posts a message in a channel associated with the webhook URL.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">slack_sdk.webhook</span> <span class="kn">import</span> <span class="n">WebhookClient</span>
<span class="n">url</span> <span class="o">=</span> <span class="s2">&quot;https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX&quot;</span>
<span class="n">webhook</span> <span class="o">=</span> <span class="n">WebhookClient</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>

<span class="n">response</span> <span class="o">=</span> <span class="n">webhook</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">text</span><span class="o">=</span><span class="s2">&quot;Hello!&quot;</span><span class="p">)</span>
<span class="k">assert</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">200</span>
<span class="k">assert</span> <span class="n">response</span><span class="o">.</span><span class="n">body</span> <span class="o">==</span> <span class="s2">&quot;ok&quot;</span>
</pre></div>
</div>
<p>It’s also possible to use <code class="docutils literal notranslate"><span class="pre">blocks</span></code>, richer message using <a class="reference external" href="https://api.slack.com/block-kit">Block Kit</a>.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">slack_sdk.webhook</span> <span class="kn">import</span> <span class="n">WebhookClient</span>
<span class="n">url</span> <span class="o">=</span> <span class="s2">&quot;https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX&quot;</span>
<span class="n">webhook</span> <span class="o">=</span> <span class="n">WebhookClient</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">webhook</span><span class="o">.</span><span class="n">send</span><span class="p">(</span>
    <span class="n">text</span><span class="o">=</span><span class="s2">&quot;fallback&quot;</span><span class="p">,</span>
    <span class="n">blocks</span><span class="o">=</span><span class="p">[</span>
        <span class="p">{</span>
            <span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;section&quot;</span><span class="p">,</span>
            <span class="s2">&quot;text&quot;</span><span class="p">:</span> <span class="p">{</span>
                <span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;mrkdwn&quot;</span><span class="p">,</span>
                <span class="s2">&quot;text&quot;</span><span class="p">:</span> <span class="s2">&quot;You have a new request:</span><span class="se">\n</span><span class="s2">*&lt;fakeLink.toEmployeeProfile.com|Fred Enriquez - New device request&gt;*&quot;</span>
            <span class="p">}</span>
        <span class="p">}</span>
    <span class="p">]</span>
<span class="p">)</span>
</pre></div>
</div>
</section>
<section id="response-url">
<h2>response_url<a class="headerlink" href="#response-url" title="Link to this heading">¶</a></h2>
<p>User actions in channels generates a <a class="reference external" href="https://api.slack.com/interactivity/handling#message_responses">response_url</a> and includes the URL in its payload. You can use <code class="docutils literal notranslate"><span class="pre">WebhookClient</span></code> to send a message via the <code class="docutils literal notranslate"><span class="pre">response_url</span></code>.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">from</span> <span class="nn">slack_sdk.signature</span> <span class="kn">import</span> <span class="n">SignatureVerifier</span>
<span class="n">signature_verifier</span> <span class="o">=</span> <span class="n">SignatureVerifier</span><span class="p">(</span>
    <span class="n">signing_secret</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s2">&quot;SLACK_SIGNING_SECRET&quot;</span><span class="p">]</span>
<span class="p">)</span>

<span class="kn">from</span> <span class="nn">slack_sdk.webhook</span> <span class="kn">import</span> <span class="n">WebhookClient</span>

<span class="kn">from</span> <span class="nn">flask</span> <span class="kn">import</span> <span class="n">Flask</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">make_response</span>
<span class="n">app</span> <span class="o">=</span> <span class="n">Flask</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>

<span class="nd">@app</span><span class="o">.</span><span class="n">route</span><span class="p">(</span><span class="s2">&quot;/slack/events&quot;</span><span class="p">,</span> <span class="n">methods</span><span class="o">=</span><span class="p">[</span><span class="s2">&quot;POST&quot;</span><span class="p">])</span>
<span class="k">def</span> <span class="nf">slack_app</span><span class="p">():</span>
    <span class="c1"># Verify incoming requests from Slack</span>
    <span class="c1"># https://api.slack.com/authentication/verifying-requests-from-slack</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">signature_verifier</span><span class="o">.</span><span class="n">is_valid</span><span class="p">(</span>
        <span class="n">body</span><span class="o">=</span><span class="n">request</span><span class="o">.</span><span class="n">get_data</span><span class="p">(),</span>
        <span class="n">timestamp</span><span class="o">=</span><span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;X-Slack-Request-Timestamp&quot;</span><span class="p">),</span>
        <span class="n">signature</span><span class="o">=</span><span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;X-Slack-Signature&quot;</span><span class="p">)):</span>
        <span class="k">return</span> <span class="n">make_response</span><span class="p">(</span><span class="s2">&quot;invalid request&quot;</span><span class="p">,</span> <span class="mi">403</span><span class="p">)</span>

    <span class="c1"># Handle a slash command invocation</span>
    <span class="k">if</span> <span class="s2">&quot;command&quot;</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">form</span> \
        <span class="ow">and</span> <span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="p">[</span><span class="s2">&quot;command&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;/reply-this&quot;</span><span class="p">:</span>
        <span class="n">response_url</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="p">[</span><span class="s2">&quot;response_url&quot;</span><span class="p">]</span>
        <span class="n">text</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">form</span><span class="p">[</span><span class="s2">&quot;text&quot;</span><span class="p">]</span>
        <span class="n">webhook</span> <span class="o">=</span> <span class="n">WebhookClient</span><span class="p">(</span><span class="n">response_url</span><span class="p">)</span>
        <span class="c1"># Send a reply in the channel</span>
        <span class="n">response</span> <span class="o">=</span> <span class="n">webhook</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">text</span><span class="o">=</span><span class="sa">f</span><span class="s2">&quot;You said &#39;</span><span class="si">{</span><span class="n">text</span><span class="si">}</span><span class="s2">&#39;&quot;</span><span class="p">)</span>
        <span class="c1"># Acknowledge this request</span>
        <span class="k">return</span> <span class="n">make_response</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>

    <span class="k">return</span> <span class="n">make_response</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="mi">404</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="asyncwebhookclient">
<h2>AsyncWebhookClient<a class="headerlink" href="#asyncwebhookclient" title="Link to this heading">¶</a></h2>
<p>The webhook client is available in asynchronous programming using the standard <a class="reference external" href="https://docs.python.org/3/library/asyncio.html">asyncio</a> library, too. You use <code class="docutils literal notranslate"><span class="pre">AsyncWebhookClient</span></code> instead for it.</p>
<p><code class="docutils literal notranslate"><span class="pre">AsyncWebhookClient</span></code> internally relies on <a class="reference external" href="https://docs.aiohttp.org/en/stable/">AIOHTTP</a> library but it is an optional dependency. So, to use this class, run <code class="docutils literal notranslate"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">aiohttp</span></code> beforehand.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="c1"># requires: pip install aiohttp</span>
<span class="kn">from</span> <span class="nn">slack_sdk.webhook.async_client</span> <span class="kn">import</span> <span class="n">AsyncWebhookClient</span>
<span class="n">url</span> <span class="o">=</span> <span class="s2">&quot;https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX&quot;</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">send_message_via_webhook</span><span class="p">(</span><span class="n">url</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
    <span class="n">webhook</span> <span class="o">=</span> <span class="n">AsyncWebhookClient</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
    <span class="n">response</span> <span class="o">=</span> <span class="k">await</span> <span class="n">webhook</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">text</span><span class="o">=</span><span class="s2">&quot;Hello!&quot;</span><span class="p">)</span>
    <span class="k">assert</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">200</span>
    <span class="k">assert</span> <span class="n">response</span><span class="o">.</span><span class="n">body</span> <span class="o">==</span> <span class="s2">&quot;ok&quot;</span>

<span class="c1"># This is the simplest way to run the async method</span>
<span class="c1"># but you can go with any ways to run it</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">send_message_via_webhook</span><span class="p">(</span><span class="n">url</span><span class="p">))</span>
</pre></div>
</div>
</section>
<hr class="docutils" />
<section id="retryhandler">
<h2>RetryHandler<a class="headerlink" href="#retryhandler" title="Link to this heading">¶</a></h2>
<p>With the default settings, only <code class="docutils literal notranslate"><span class="pre">ConnectionErrorRetryHandler</span></code> with its default configuration (=only one retry in the manner of <a class="reference external" href="https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/">exponential backoff and jitter</a>) is enabled. The retry handler retries if an API client encounters a connectivity-related failure (e.g., Connection reset by peer).</p>
<p>To use other retry handlers, you can pass a list of <code class="docutils literal notranslate"><span class="pre">RetryHandler</span></code> to the client constructor. For instance, you can add the built-in <code class="docutils literal notranslate"><span class="pre">RateLimitErrorRetryHandler</span></code> this way:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">slack_sdk.webhook</span> <span class="kn">import</span> <span class="n">WebhookClient</span>
<span class="n">url</span> <span class="o">=</span> <span class="s2">&quot;https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX&quot;</span>
<span class="n">webhook</span> <span class="o">=</span> <span class="n">WebhookClient</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="n">url</span><span class="p">)</span>

<span class="c1"># This handler does retries when HTTP status 429 is returned</span>
<span class="kn">from</span> <span class="nn">slack_sdk.http_retry.builtin_handlers</span> <span class="kn">import</span> <span class="n">RateLimitErrorRetryHandler</span>
<span class="n">rate_limit_handler</span> <span class="o">=</span> <span class="n">RateLimitErrorRetryHandler</span><span class="p">(</span><span class="n">max_retry_count</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>

<span class="c1"># Enable rate limited error retries as well</span>
<span class="n">client</span><span class="o">.</span><span class="n">retry_handlers</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rate_limit_handler</span><span class="p">)</span>
</pre></div>
</div>
<p>Creating your own ones is also quite simple. Defining a new class that inherits <code class="docutils literal notranslate"><span class="pre">slack_sdk.http_retry.RetryHandler</span></code> (<code class="docutils literal notranslate"><span class="pre">AsyncRetryHandler</span></code> for asyncio apps) and implements required methods (internals of <code class="docutils literal notranslate"><span class="pre">can_retry</span></code> / <code class="docutils literal notranslate"><span class="pre">prepare_for_next_retry</span></code>). Check the built-in ones’ source code for learning how to properly implement.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">socket</span>
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Optional</span>
<span class="kn">from</span> <span class="nn">slack_sdk.http_retry</span> <span class="kn">import</span> <span class="p">(</span><span class="n">RetryHandler</span><span class="p">,</span> <span class="n">RetryState</span><span class="p">,</span> <span class="n">HttpRequest</span><span class="p">,</span> <span class="n">HttpResponse</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">slack_sdk.http_retry.builtin_interval_calculators</span> <span class="kn">import</span> <span class="n">BackoffRetryIntervalCalculator</span>
<span class="kn">from</span> <span class="nn">slack_sdk.http_retry.jitter</span> <span class="kn">import</span> <span class="n">RandomJitter</span>

<span class="k">class</span> <span class="nc">MyRetryHandler</span><span class="p">(</span><span class="n">RetryHandler</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">_can_retry</span><span class="p">(</span>
        <span class="bp">self</span><span class="p">,</span>
        <span class="o">*</span><span class="p">,</span>
        <span class="n">state</span><span class="p">:</span> <span class="n">RetryState</span><span class="p">,</span>
        <span class="n">request</span><span class="p">:</span> <span class="n">HttpRequest</span><span class="p">,</span>
        <span class="n">response</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">HttpResponse</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
        <span class="n">error</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="ne">Exception</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
    <span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
        <span class="c1"># [Errno 104] Connection reset by peer</span>
        <span class="k">return</span> <span class="n">error</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">error</span><span class="p">)</span> <span class="ow">and</span> <span class="n">error</span><span class="o">.</span><span class="n">errno</span> <span class="o">==</span> <span class="mi">104</span>

<span class="n">webhook</span> <span class="o">=</span> <span class="n">WebhookClient</span><span class="p">(</span>
    <span class="n">url</span><span class="o">=</span><span class="n">url</span><span class="p">,</span>
    <span class="n">retry_handlers</span><span class="o">=</span><span class="p">[</span><span class="n">MyRetryHandler</span><span class="p">(</span>
        <span class="n">max_retry_count</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span>
        <span class="n">interval_calculator</span><span class="o">=</span><span class="n">BackoffRetryIntervalCalculator</span><span class="p">(</span>
            <span class="n">backoff_factor</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span>
            <span class="n">jitter</span><span class="o">=</span><span class="n">RandomJitter</span><span class="p">(),</span>
        <span class="p">),</span>
    <span class="p">)],</span>
<span class="p">)</span>
</pre></div>
</div>
<p>For asyncio apps, <code class="docutils literal notranslate"><span class="pre">Async</span></code> prefixed corresponding modules are available. All the methods in those methods are async/await compatible. Check <a class="reference external" href="https://github.com/slackapi/python-slack-sdk/blob/main/slack_sdk/http_retry/async_handler.py">the source code</a> and <a class="reference external" href="https://github.com/slackapi/python-slack-sdk/blob/main/tests/slack_sdk_async/web/test_async_web_client_http_retry.py">tests</a> for more details.</p>
</section>
</section>


                        <div class="clear_both large_bottom_margin"></div>
                    </div>
                </div>
                <!-- /Body Content -->
            </div>
        </div>

        <footer>
            <p class="light tiny align_center">
                © 2015- Slack Technologies, LLC and contributors
            </p>
        </footer>

        <script>
            window.ga =
                window.ga ||
                function() {
                    (ga.q = ga.q || []).push(arguments);
                };
            ga.l = +new Date();
            ga('create', 'UA-56978219-13', 'auto');
            ga('send', 'pageview');
        </script>
        <script async src="https://www.google-analytics.com/analytics.js"></script>
    </body>
</html>